/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pki;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.security.Security;
import java.security.cert.CertificateFactory;
import java.security.cert.X509CRL;
import java.security.cert.X509CRLEntry;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.bouncycastle.x509.X509V2CRLGenerator;
import sun.misc.BASE64Encoder;

/**
 *
 * @author Szaboh
 */
public class CRLTools {
    
    private X509CRL crl;
    String username;
    
    public static boolean exists(String username){
        return new File(PKIService.revocationPath+username+".crl").exists();
    }
    
    public CRLTools(String username){
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        this.username = username;
        
        if(exists(this.username)){
            try{
                CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
                InputStream crlStream = new BufferedInputStream(new FileInputStream(PKIService.revocationPath+username+".crl"));
                crl = (X509CRL) certFactory.generateCRL(crlStream);
                crlStream.close();
            }catch(Exception e){
                e.printStackTrace();
            }
        }else{
            try{
                X509V2CRLGenerator crlGen = new X509V2CRLGenerator();
                X509Certificate caCert = (X509Certificate) KeyStoreTools.getCertificateTopLevel();
                Calendar cal = new GregorianCalendar();
                Date now = cal.getTime();             
                
                crlGen.setThisUpdate(now);
                crlGen.setIssuerDN(caCert.getIssuerX500Principal());
                crlGen.setSignatureAlgorithm(caCert.getSigAlgName());
                crl = crlGen.generateX509CRL(KeyStoreTools.getPrivateKeyTopLevel(), "BC");
            }catch(Exception e){
                e.printStackTrace();
            }
        }

    }
    
    public void write(){
        try{
            FileOutputStream out = new FileOutputStream(new File(PKIService.revocationPath+username+".crl"));
            out.write("-----BEGIN CERTIFICATE-----\n".getBytes());
            out.write(new BASE64Encoder().encode(crl.getEncoded()).getBytes());
            out.write("\n-----END CERTIFICATE-----\n".getBytes());
            out.close();
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    public void addRevocation(X509Certificate cert, int reason){
        Calendar cal = new GregorianCalendar();
        Date now = cal.getTime();
        
        try{
            X509V2CRLGenerator crlGen = new X509V2CRLGenerator();
            X509Certificate caCert = (X509Certificate) KeyStoreTools.getCertificateTopLevel();
            
            crlGen.setIssuerDN(caCert.getIssuerX500Principal());
            crlGen.setSignatureAlgorithm(caCert.getSigAlgName());
            crlGen.addCRL(crl);
            crlGen.setThisUpdate(now);
            crlGen.addCRLEntry(cert.getSerialNumber(), now, reason);

            crl = crlGen.generate(KeyStoreTools.getPrivateKeyTopLevel(), "BC");
        }catch(Exception e){
            e.printStackTrace();
        }
    }
    
    public boolean isRevoked(X509Certificate cert){
        return crl.isRevoked(cert);
    }
    
    public List<X509CRLEntry> getRevocationList(){
       ArrayList<X509CRLEntry> l = new ArrayList<>();
       Set crls = crl.getRevokedCertificates();
       Iterator i = crls.iterator();
        
       while(i.hasNext()) l.add((X509CRLEntry) i.next());
       
       return l;
    }
    
}
